using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using elibrary.Classes;
using elibrary.Models;
using elibrary.Models.Entities;
using NoticeType = elibrary.Models.Entities.Notice.NoticeType;

namespace elibrary.Models.Managers
{
	public class NoticeManager
	{
		private DataContext ctx;
		private DbSet<Notice> notices;

		public NoticeManager(DataContext ctx)
		{
			this.ctx = ctx;
			this.notices = ctx.notices;
		}

		public void add(Notice notice,bool autoSave=true)
		{
			notices.Add(notice);

			if (autoSave)
				ctx.SaveChanges();
		}

		public Notice get(int id)
		{
			return notices.SingleOrDefault(q => q.id == id);
		}

		public List<Notice> getAllActiveNotice()
		{
			return Utilities.ensureRs<Notice>(notices.Where(q => q.enabled == true));
		}

		public List<Notice> getAllActiveNotice(int uid)
		{
			return Utilities.ensureRs<Notice>(notices.Where(q => q.enabled && q.userId == uid));
		}

		public List<Notice> getAllActiveNotice(NoticeType ntype,int uid)
		{
			return Utilities.ensureRs<Notice>(notices.Where(q => q.enabled && q.type == ntype 
				&& q.userId == uid));
		}

		public List<Notice> getAllActiveNotice(NoticeType ntype)
		{
			return Utilities.ensureRs<Notice>(notices.Where(q => q.enabled == true && 
				q.type == ntype));
		}

		public List<Notice> getActiveNoticesForUser(int uid,Dictionary<string,bool> flags)
		{
			List<Notice> results = new List<Notice>();
			List<Notice> active = getAllActiveNotice(uid);
            bool test = false;

			if (flags.ContainsKey("profile") && (test = flags["profile"]))
			{
				var rs = active.SingleOrDefault(q => q.type == NoticeType.UpdateProfile);
				
				if (rs != null)
					results.Add(rs);
			}

			if (flags.ContainsKey("cart") && (test = flags["cart"]))
			{
				var rs = active.SingleOrDefault(q => q.type == NoticeType.CartExpired);

				if (rs != null)
				{
					results.Add(rs);
					rs.disableMe();
				}
			}

			if (flags.ContainsKey("order") && (test = flags["order"]))
			{
				var rs = Utilities.ensureRs<Notice>(active.Where(q => q.type == NoticeType.OrderCancelled
					|| q.type == NoticeType.OrderConfirmed));

				foreach (var notice in rs)
				{
					results.Add(notice);
					notice.disableMe();
				}
			}

            if (flags.ContainsKey("payment") && (test = flags["payment"]))
            {
                var rs = active.SingleOrDefault(q => q.type == NoticeType.PaymentRejected);

                if (rs != null)
                {
                    results.Add(rs);
                    rs.disableMe();
                }
            }

            if (flags.ContainsKey("book") && (test = flags["book"]))
            {
                var rs = Utilities.ensureRs<Notice>(active.Where(q => q.type == NoticeType.BookSold));
                results.AddRange(rs);

                rs = Utilities.ensureRs<Notice>(active.Where(q => q.type == NoticeType.BookApproved));
                results.AddRange(rs);

                rs = Utilities.ensureRs<Notice>(active.Where(q => q.type == NoticeType.BookUploadImage));
                results.AddRange(rs);
            }

			return results;
		}

		public Notice getActiveNotice(NoticeType ntype,int aid)
		{
			return notices.SingleOrDefault(q => q.type == ntype && q.associatedId == aid);
		}

		public void delete(int nid, bool autoSave=true)
		{
			delete(get(nid),autoSave);
		}

		public void delete(Notice notice, bool autoSave=true)
		{
			if (notice != null)
			{
				notices.Remove(notice);
				
				if (autoSave)
					ctx.SaveChanges();
			}
		}
	}
}